package com.fox.matrix;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


public class HttpClientT {
    Logger logger = LoggerFactory.getLogger(HttpClientT.class);
    public static final String ROUTE_MATRIX_AK = "FI3aXG0ICe95W9xin2uTwPmgQOb2kH95";
    public static final String ROUTE_MATRIX_URL = "http://api.map.baidu.com/routematrix/v2/driving?origins=%s&destinations=%s&output=json&ak=%s";

    private String doGet(String url) throws IOException {
        //创建CloseableHttpClient
        HttpClientBuilder builder = HttpClientBuilder.create();
        CloseableHttpClient client = builder.build();
        //执行
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        return entity == null ? null : EntityUtils.toString(entity, "utf-8");
    }

    public List<RouteInfo> getRouteMatrix(Coordinate origin, List<Coordinate> destinations) throws RouteMatrixException {
        if (destinations == null || origin == null || destinations.size() == 0)
            return new ArrayList<>(0);
        //查看数据库里是否存在

        //不存在发起调用
        StringBuilder sb = new StringBuilder();
        for (Coordinate destination : destinations) {
            sb.append(destination.toString() + "|");
        }
        String des = sb.toString();
        des = des.substring(0, des.length() - 1);
        String ori = origin.toString();
        //捕获是因为绝对不会报错..
        try {
            des = URLEncoder.encode(des, "utf-8");
            ori = URLEncoder.encode(origin.toString(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String url = String.format(ROUTE_MATRIX_URL, ori, des, ROUTE_MATRIX_AK);
        //将异常变成RouteMatrixException
        String result = null;
        try {
            result = doGet(url);
        } catch (IOException e) {
            throw new RouteMatrixException("出现IO异常");
        }
        //尝试捕获运行时异常 如果抛出一定是出现返回值格式错误的情况
        //比如api不可用..或者被统一拦截了.
        Map<String, Object> map = null;
        try {
            map = (Map<String, Object>) JSON.parse(result);
        } catch (JSONException e) {
            logger.debug("返回结果转成json出错 {}", result);
        }
        //初始化容量应该和终点条数一样
        List<RouteInfo> list = new ArrayList<>(destinations.size());
        List<Map<String, Map<String, Object>>> resList = (List<Map<String, Map<String, Object>>>) map.get("result");
        for (int i = 0; i < resList.size(); i++) {
            Map<String, Map<String, Object>> m = resList.get(i);
            int distance = (int) m.get("distance").get("value");
            int duration = (int) m.get("duration").get("value");
            Coordinate destination = destinations.get(i);
            RouteInfo routeInfo = new RouteInfo(origin, destination, distance, duration);
            //百度api上写的没有计算结果的情况
            if (distance == 0 || duration == 0)
                routeInfo.setExistResult(false);
            list.add(routeInfo);
        }
        //升序排列 最小的在第一格
        list.sort((a,b)->a.getDistance()>b.getDistance()?1:-1);
        return list;
    }

    public static void main(String[] args) throws Exception {
        Coordinate c0 = new Coordinate(30.256374576402054, 120.16831257927723, "集贤亭");
        Coordinate c1 = new Coordinate(30.250811490415374, 120.18427625151195, "五柳巷");
        Coordinate c2 = new Coordinate(30.368375794068109, 120.02130575662059, "良渚文化村");
        Coordinate c3 = new Coordinate(30.16862228684402, 120.21748073399272, "白马湖");
        List<Coordinate> list = Arrays.asList(c1, c2, c3);
        new HttpClientT().getRouteMatrix(c0, list).forEach(routeInfo -> System.out.println(routeInfo.getDistance()));

    }
}
